//
//  NSDate+BirthDay.m
//  
//
//  Created by 罗亮富 on 12-12-6.
//  Copyright (c) 2012年  All rights reserved.
//

#define SECOND_PER_DAY 86400L


#import "NSDate+Utility.h"
#import <sys/sysctl.h>

static NSDateFormatter *_internetDateTimeFormatter = nil;

@implementation NSDate (Utility)

- (NSInteger)year {
    return [[[NSCalendar currentCalendar] components:NSCalendarUnitYear fromDate:self] year];
}

- (NSInteger)month {
    return [[[NSCalendar currentCalendar] components:NSCalendarUnitMonth fromDate:self] month];
}

- (NSInteger)day {
    return [[[NSCalendar currentCalendar] components:NSCalendarUnitDay fromDate:self] day];
}

- (NSInteger)hour {
    return [[[NSCalendar currentCalendar] components:NSCalendarUnitHour fromDate:self] hour];
}

- (NSInteger)minute {
    return [[[NSCalendar currentCalendar] components:NSCalendarUnitMinute fromDate:self] minute];
}

- (NSInteger)second {
    return [[[NSCalendar currentCalendar] components:NSCalendarUnitSecond fromDate:self] second];
}

- (NSInteger)nanosecond {
    return [[[NSCalendar currentCalendar] components:NSCalendarUnitSecond fromDate:self] nanosecond];
}

- (NSInteger)weekday {
    return [[[NSCalendar currentCalendar] components:NSCalendarUnitWeekday fromDate:self] weekday];
}

- (NSInteger)weekdayOrdinal {
    return [[[NSCalendar currentCalendar] components:NSCalendarUnitWeekdayOrdinal fromDate:self] weekdayOrdinal];
}

- (NSInteger)weekOfMonth {
    return [[[NSCalendar currentCalendar] components:NSCalendarUnitWeekOfMonth fromDate:self] weekOfMonth];
}

- (NSInteger)weekOfYear {
    return [[[NSCalendar currentCalendar] components:NSCalendarUnitWeekOfYear fromDate:self] weekOfYear];
}

- (NSInteger)yearForWeekOfYear {
    return [[[NSCalendar currentCalendar] components:NSCalendarUnitYearForWeekOfYear fromDate:self] yearForWeekOfYear];
}

- (NSInteger)quarter {
    return [[[NSCalendar currentCalendar] components:NSCalendarUnitQuarter fromDate:self] quarter];
}

- (BOOL)isLeapMonth {
    return [[[NSCalendar currentCalendar] components:NSCalendarUnitQuarter fromDate:self] isLeapMonth];
}

- (BOOL)isLeapYear {
    NSUInteger year = self.year;
    return ((year % 400 == 0) || (year % 100 == 0) || (year % 4 == 0));
}

- (BOOL)isToday {
    if (fabs(self.timeIntervalSinceNow) >= 60 * 60 * 24) return NO;
    return [NSDate new].day == self.day;
}

- (BOOL)isYesterday {
    NSDate *added = [self dateByAddingDays:1];
    return [added isToday];
}

- (BOOL)isCurrentWeek
{
    NSDate *now = [NSDate new];
    if ( now.year != self.year ) {
        return NO;
    }
    
    return now.weekOfYear == self.weekOfYear;
}

- (BOOL)isAM
{
    long long ret = [self timeIntervalSince1970];
    NSTimeInterval dayTime = ret % 86400;
    if ( dayTime < 14400 ) {
        return YES;
    }
    
    return NO;
}

- (NSInteger)daysInMonth
{
    NSRange daysInLastMonth = [[NSCalendar currentCalendar] rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:self];
    return daysInLastMonth.length;
}

- (BOOL)isLastDayInMonth
{
    NSInteger daysInMonth = [self daysInMonth];
    NSInteger day = [self day];
    
    if ( daysInMonth == day ) {
        return YES;
    }
    
    return NO;
}



- (NSDate *)dateByAddingDays:(NSInteger)days {
    NSTimeInterval aTimeInterval = [self timeIntervalSinceReferenceDate] + 86400 * days;
    NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval];
    return newDate;
}


-(NSInteger)ageAsBirthDay
{
    NSDate *today = [NSDate date];
    NSCalendar *currentCalendar = [NSCalendar autoupdatingCurrentCalendar];
    unsigned unitFlags = NSCalendarUnitYear;
    NSDateComponents *component= [currentCalendar components:unitFlags fromDate:self toDate:today options:0];
    return component.year;
}

/***************************************
 水瓶座：1月21日 - 2月19日
 双鱼座：2月20日 - 3月20日
 白羊座：3月21日 - 4月20日
 金牛座：4月21日 - 5月21日
 双子座：5月22日 - 6月21日
 巨蟹座：6月22日 - 7月22日
 狮子座：7月23日 - 8月23日
 处女座：8月24日 - 9月23日
 天秤座：9月24日 - 10月23日
 天蝎座：10月24日 - 11月22日
 射手座：11月23日 - 12月21日
 魔羯座：12月22日 - 1月20日
 *************************************/
-(NSString *)constellationAsBirthDay
{
    NSArray *constellations = [NSArray arrayWithObjects:
                               NSLocalizedString(@"水瓶座",nil),
                               NSLocalizedString(@"双鱼座",nil),
                               NSLocalizedString(@"白羊座",nil),
                               NSLocalizedString(@"金牛座",nil),
                               NSLocalizedString(@"双子座",nil),
                               NSLocalizedString(@"巨蟹座",nil),
                               NSLocalizedString(@"狮子座",nil),
                               NSLocalizedString(@"处女座",nil),
                               NSLocalizedString(@"天秤座",nil),
                               NSLocalizedString(@"天蝎座",nil),
                               NSLocalizedString(@"射手座",nil),
                               NSLocalizedString(@"摩羯座",nil),
                               nil];
    
    DateType constellationsStarts[12]={{1,21},{2,20},{3,21},{4,21},{5,22},{6,22},{7.23},{8,24},{9,24},{10,24},{11,23},{12,22}};
    
    NSDateFormatter* formatter = [[NSDateFormatter alloc]init];
    [formatter setDateFormat:@"MMdd"];
    NSString *dateStr = [formatter stringFromDate:self];
    unsigned char tmonth = (unsigned char)[[dateStr substringWithRange:NSMakeRange(0, 2)] integerValue];
    unsigned char tday = (unsigned char)[[dateStr substringWithRange:NSMakeRange(2, 2)] integerValue];
    int i;
    for(i=0; i<12; i++)
    {
        int next = i+1;
        if(next>11)
            next = 0;
        
        if((constellationsStarts[i].month==tmonth && constellationsStarts[i].date<=tday)
           ||(constellationsStarts[next].month==tmonth && constellationsStarts[next].date>tday))
        {
            break;
        }
    }
    return [constellations objectAtIndex:i];
}

-(BOOL)isOtherDayFromDate:(NSDate *)otherDay;
{
    if(!otherDay)
        return YES;
    
    NSInteger fullDay = (NSInteger)[self timeIntervalSinceDate:otherDay]/SECOND_PER_DAY;
    if(fullDay>0)
        return YES;
   
    NSCalendarUnit unit = NSCalendarUnitDay|NSCalendarUnitMonth|NSCalendarUnitYear;
    NSCalendar *calendar = [NSCalendar currentCalendar];
#warning crash -[__NSCFCalendar components:fromDate:] + 724 \_objc_msgSend_uncached\lookUpImpOrForward EXC_CRASH (SIGABRT)
    NSDateComponents *componentsSelf = [calendar components:unit fromDate:self];
    NSDateComponents *componentsOther = [calendar components:unit fromDate:otherDay];
    if([componentsSelf day] == [componentsOther day]
       && [componentsSelf year] == [componentsOther year]
       && [componentsSelf month] == [componentsOther month])
        return NO;
    
    return YES;
}

-(BOOL)isOtherMonthFromDate:(NSDate *)otherDay
{
    if(!otherDay)
        return YES;
    
    NSInteger fullDay = (NSInteger)[self timeIntervalSinceDate:otherDay]/SECOND_PER_DAY;
    if(fullDay>31)
        return YES;
    
    NSCalendarUnit unit = NSCalendarUnitMonth|NSCalendarUnitYear;
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *componentsSelf = [calendar components:unit fromDate:self];
    NSDateComponents *componentsOther = [calendar components:unit fromDate:otherDay];
    if([componentsSelf year] == [componentsOther year] &&
       [componentsSelf month] == [componentsOther month])
        return NO;
    
    return YES;
}

-(BOOL)isOtherYearFromDate:(NSDate *)otherDay
{
    if(!otherDay)
        return YES;
    
    NSInteger fullDay = (NSInteger)[self timeIntervalSinceDate:otherDay]/SECOND_PER_DAY;
    if(fullDay>366)
        return YES;
    
    NSCalendarUnit unit = NSCalendarUnitYear;
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *componentsSelf = [calendar components:unit fromDate:self];
    NSDateComponents *componentsOther = [calendar components:unit fromDate:otherDay];
    if([componentsSelf year] == [componentsOther year])
        return NO;
    
    return YES;
}

+(NSDate *)dateFromFormatedString:(NSString *)formatString
{
    NSDate *date;
    NSDateFormatter* formatter = [[NSDateFormatter alloc]init];
    [formatter setDateFormat:TIME_FORMAT_DEFAULT];
    date = [formatter dateFromString:formatString];
    return date;
}

+(NSDate *)dateFromFormatedString:(NSString *)formatString byFormat:(NSString *)format
{
    if(!formatString)
        return nil;
    
    NSDate *date;
    NSDateFormatter* formatter = [[NSDateFormatter alloc]init];
    [formatter setDateFormat:format];
    date = [formatter dateFromString:formatString];
    return date;
}

-(NSString *)dateStringWithFormat:(NSString *)formatString
{
    NSDateFormatter* formatter = [[NSDateFormatter alloc]init];
    [formatter setDateFormat:formatString];
    return [formatter stringFromDate:self];
}

-(NSString *)appDateDescription
{
    return [self dateStringWithFormat:TIME_FORMAT_DEFAULT];
}

-(NSString *)defaultDescription
{
    return [self dateStringWithFormat:@"yyyy-MM-dd HH:mm:ss"];
}
-(NSString*)dateStringFromNow
{
    NSString* timeStr;
    NSTimeInterval now  = [[NSDate date] timeIntervalSince1970];
    NSTimeInterval old = [self timeIntervalSince1970];
    NSTimeInterval component = fabs( now - old);
    NSInteger speTime = component/(3600*24);
    if ( speTime >=20&&speTime<=24)
    {
        
        timeStr = NSLocalizedString(@"1天以前", nil);
        
    }
    else if ( speTime <20)
    {
        timeStr = [NSString stringWithFormat:NSLocalizedString(@"%lld小时前", nil),speTime+1];
    }
    else if(speTime >24&&speTime<=48)
    {
        timeStr = NSLocalizedString(@"2天以前", nil);
    }
    else if(speTime >48&&speTime<=74)
    {
        timeStr = NSLocalizedString(@"3天以前", nil);
    }
    else if(speTime >74&&speTime<=168)
    {
        timeStr = NSLocalizedString(@"一周以内", nil);
        
    }
    else
    {
        timeStr = NSLocalizedString(@"一个月以内", nil);
        
    }
    return timeStr;
}

-(NSString*)timeStringFromNowIsShowDetail:(BOOL)isShowDetail
{
    NSString* timeStr;
    NSTimeInterval now  = [[NSDate date] timeIntervalSince1970];
    NSTimeInterval old = [self timeIntervalSince1970];
    NSTimeInterval component = now - old;
    long speTime = component/(3600*24);  //单位 天
    
    if (speTime < 1) { //一天内
        long detailTime = component/3600;  //单位 小时
        
        if (isShowDetail) { //显示具体
            if (detailTime < 1) { //一小时内
                if (component < 60) { //一分钟内
                    timeStr = [NSString stringWithFormat:NSLocalizedString(@"%d s 前", nil), (short)component%60];
                }else {
                    timeStr = [NSString stringWithFormat:NSLocalizedString(@"%d min %d s 前", nil),(short)component/60, (short)component%60];
                }
            }else {
                timeStr = [NSString stringWithFormat:NSLocalizedString(@"%lld h %d min 前", nil),detailTime, (short)component%3600/60];
            }
        }
        else { //不显示具体
            if (detailTime < 1) { //一小时内
                if (component < 60) { //一分钟内
                    timeStr = NSLocalizedString(@"刚刚", nil);
                }else {
                    timeStr = [NSString stringWithFormat:NSLocalizedString(@"%d分钟前", nil),(short)component/60];
                }
            }else {
                timeStr = [NSString stringWithFormat:NSLocalizedString(@"%lld小时前", nil),detailTime];
            }
        }
    }
    else if (speTime<=2)
    {
        timeStr = NSLocalizedString(@"1天以前", nil);
    }
    else if(speTime<=3)
    {
        timeStr = NSLocalizedString(@"2天以前", nil);
    }
    else if(speTime<=4)
    {
        timeStr = NSLocalizedString(@"3天以前", nil);
    }
    else if(speTime<=6) //6.999(7天)取整数部分是6，所以这里是6
    {
        timeStr = NSLocalizedString(@"一周以内", nil);
    }
    else if(speTime<=30)
    {
        timeStr = NSLocalizedString(@"一个月以内", nil);
    }
    else {
        timeStr = NSLocalizedString(@"一个月以前", nil);
    }
    return timeStr;
}

//动态时间
-(NSString*)dynamicTimeString
{
    NSString* timeStr;
    NSTimeInterval now  = [[NSDate date] timeIntervalSince1970];
    NSTimeInterval old = [self timeIntervalSince1970];
    NSTimeInterval component = now - old;
    long speTime = component/(3600*24);  //单位 天
    
    if (speTime < 1) { //一天内
        long detailTime = component/3600;  //单位 小时
        
        if (detailTime < 1) { //一小时内
            if (component < 60) { //一分钟内
                timeStr = NSLocalizedString(@"刚刚", nil);
            }else {
                timeStr = [NSString stringWithFormat:NSLocalizedString(@"%d分钟前", nil),(short)component/60];
            }
        }else {
            timeStr = [NSString stringWithFormat:NSLocalizedString(@"%lld小时前", nil),detailTime];
        }
    }
    else if (speTime < 31)
    {
        timeStr = [NSString stringWithFormat:NSLocalizedString(@"%lld天以前", nil), speTime];
    }
    else {
        NSCalendar *calendar = [NSCalendar currentCalendar];
        NSDate *date = [NSDate date];
        NSDateComponents *componentsSelf = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay
                                                       fromDate:self];
        
        NSDateComponents *componentsNow = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay
                                                      fromDate:date];
        
        if([componentsNow year] - [componentsSelf year]>0)
            return [self dateStringWithFormat:@"yyyy-MM-dd"];
        else if([componentsNow month] - [componentsSelf month] > 0)
            return [self dateStringWithFormat:@"MM-dd"];
    }
    
    return timeStr;
}

- (NSString*)favoriteTimeString
{
    NSString* timeStr;
    NSTimeInterval now  = [[NSDate date] timeIntervalSince1970];
    NSTimeInterval old = [self timeIntervalSince1970];
    NSTimeInterval component = now - old;
    long speTime = component/(3600*24);  //单位 天
    
    if (speTime < 1) { //一天内
        long detailTime = component/3600;  //单位 小时
        
        if (detailTime < 1) { //一小时内
            if (component < 60) { //一分钟内
                timeStr = NSLocalizedString(@"刚刚", nil);
            }else {
                timeStr = [NSString stringWithFormat:NSLocalizedString(@"%d分钟前", nil),(short)component/60];
            }
        }else {
            timeStr = [NSString stringWithFormat:NSLocalizedString(@"%lld小时前", nil),detailTime];
        }
    }
//    else if (speTime < 31)
//    {
//        timeStr = [NSString stringWithFormat:NSLocalizedString(@"%lld天以前", nil), speTime];
//    }
    else {
        NSCalendar *calendar = [NSCalendar currentCalendar];
        NSDate *date = [NSDate date];
    //    NSDateComponents *componentsSelf = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:self];
        
      //  NSDateComponents *componentsNow = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:date];
        
//        if([componentsNow year] - [componentsSelf year]>0)
            return [self dateStringWithFormat:@"yyyy-MM-dd"];
//        else if([componentsNow month] - [componentsSelf month] > 0)
//            return [self dateStringWithFormat:@"MM-dd"];
    }
    
    return timeStr;
}

-(NSString *)referencedDateDescription
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDate *date = [NSDate date];
    NSDateComponents *componentsSelf = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay
                                               fromDate:self];
    
    NSDateComponents *componentsNow = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay
                                               fromDate:date];

    if([componentsNow year] - [componentsSelf year]>0)
        return [self dateStringWithFormat:@"yyyy-MM-dd HH:mm"];
    else if([componentsNow month] - [componentsSelf month] > 0)
        return [self dateStringWithFormat:@"MM-dd H:mm"];
    else if([componentsNow day] - [componentsSelf day] > 2)
        return [self dateStringWithFormat:@"MM-dd H:mm"];
    else if([componentsNow day] - [componentsSelf day] == 2)//前天
    {
        return [NSString stringWithFormat:NSLocalizedString(@"前天 %@", nil),[self dateStringWithFormat:@"H:mm"]];
    }
    else if([componentsNow day] - [componentsSelf day] == 1)//昨天
    {
        return [NSString stringWithFormat:NSLocalizedString(@"昨天 %@", nil),[self dateStringWithFormat:@"H:mm"]];
    }
    else //今天
        return [NSString stringWithFormat:NSLocalizedString(@"今天 %@", nil),[self dateStringWithFormat:@"H:mm"]];
    
    
    return nil;
}

+(NSString *)timeDateFormatter:(NSDate *)date type:(int)_type
{
    //2018-11-28 lotus add: 如果date为nil，返回字符串"(null)".所以这里参数判断一下
    if (date == nil) {
        return nil;
    }
    //end.
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    switch (_type) {
        case 1:
            [dateFormatter setDateFormat:@"yyyy"];
            break;
        case 2:
            [dateFormatter setDateFormat:@"yyyy-MM"];
            break;
        case 3:
            [dateFormatter setDateFormat:@"yyyy-MM-dd"];
            break;
        case 4:
            [dateFormatter setDateFormat:@"hh"];
            break;
        case 5:
            [dateFormatter setDateFormat:@"mm"];
            break;
        case 6:
            [dateFormatter setDateFormat:@"ss"];
            break;
        case 7:
            [dateFormatter setDateFormat:@"a"];
            break;
        case 8:
            [dateFormatter setDateFormat:@"MM"];
            break;
        case 9:
            [dateFormatter setDateFormat:@"dd"];
            break;
        case 10:
            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm"];
            break;
        case 11:
            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
            break;
        case 12:
            [dateFormatter setDateFormat:@"HH:mm:ss"];
            break;
        case 13:
            [dateFormatter setDateFormat:NSLocalizedString(@"yyyy年MM月dd日 HH时mm分", nil)];
            break;
        case 14:
            [dateFormatter setDateFormat:NSLocalizedString(@"yyyy年MM月dd日", nil)];
            break;
        case 15:
            [dateFormatter setDateFormat:@"HH:mm"];
            break;
        case 16:
            [dateFormatter setDateFormat:NSLocalizedString(@"MM月dd日 HH时mm分", nil)];
            break;
        case 17:
            [dateFormatter setDateFormat:@"yyyy-MM-dd-HH-mm-ss"];
            break;
        case 18:
            [dateFormatter setDateFormat:@"yyyy.MM.dd HH:mm"];
            break;
        case 19:
            [dateFormatter setDateFormat:NSLocalizedString(@"yyyy年MM月dd日 HH:mm", nil)];
            break;
        case 20:
            [dateFormatter setDateFormat:@"yyyy.MM.dd"];
            break;
        case 21:
            [dateFormatter setDateFormat:NSLocalizedString(@"MM月dd日HH:mm", nil)];
            break;
        case 22:
            [dateFormatter setDateFormat:@"MM-dd HH:mm:ss"];
            break;
        case 23:
            [dateFormatter setDateFormat:NSLocalizedString(@"MM月dd日", nil)];
            break;
        case 24:
            [dateFormatter setDateFormat:@"MM-dd HH:mm"];
            break;
        case 25:
            [dateFormatter setDateFormat:@"MM-dd"];
            break;
        case 26:
            [dateFormatter setDateFormat:@"MM.dd"];
            break;
        case 27:
            [dateFormatter setDateFormat:NSLocalizedString(@"HH时mm分", nil)];
            break;
        default:
            break;
    }
    
    
    NSString *timeString = [NSString stringWithFormat:@"%@",[dateFormatter stringFromDate:date]];
    return timeString;
    
}


-(NSDateComponents *)datePart{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *components = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:self];
    return components;
}


-(NSDateComponents *)timePart{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *components = [calendar components:(NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond) fromDate:self];
    
    return components;
}

- (NSUInteger)daysOfMonth
{
    switch (self.datePart.month) {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            return 31;
        case 4:
        case 6:
        case 9:
        case 11:
            return 30;
        case 2:
        {
            NSInteger year = self.datePart.year;
            if (year % 100 == 0)
            {
                return (year % 400 == 0) ? 29 : 28;
            }
            else
            {
                return (year % 4 == 0) ? 29 : 28;
            }
        }
    }
    return 30;
}

-(NSUInteger)weekthOfTheYear
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    [calendar setMinimumDaysInFirstWeek:1];//设置每周至少要多少天
    NSUInteger index = [calendar ordinalityOfUnit:NSCalendarUnitWeekOfYear inUnit:NSCalendarUnitYear forDate:self];
    return index;
}

+(NSComparisonResult)compareBetweenDate:(NSDate *)date1 andDate:(NSDate *)date2{
    
    NSComparisonResult result;
    
    if ((date1 == nil && date2 == nil) || (date2 != nil && date1 != nil && [date1 compare:date2] == NSOrderedSame)) {
        result = NSOrderedSame;
    }else if((date1 != nil && date2 == nil) || [date1 compare:date2] == NSOrderedDescending){
        result = NSOrderedDescending;
    }else{
        result = NSOrderedAscending;
    }
    return result;
    
}

+ (NSInteger)daysBetweenDate:(NSDate*)fromDateTime andDate:(NSDate*)toDateTime
{
    NSDate *fromDate;
    NSDate *toDate;
    
    NSCalendar *calendar = [NSCalendar currentCalendar];
    
    [calendar rangeOfUnit:NSCalendarUnitDay startDate:&fromDate
                 interval:NULL forDate:fromDateTime];
    [calendar rangeOfUnit:NSCalendarUnitDay startDate:&toDate
                 interval:NULL forDate:toDateTime];
    
    NSDateComponents *difference = [calendar components:NSCalendarUnitDay
                                               fromDate:fromDate toDate:toDate options:0];
    
    return [difference day];
}

- (NSDate *)dateOffsetByMonth:(NSInteger)offset{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *comp = [[NSDateComponents alloc] init];
    comp.month = offset;
    return [calendar dateByAddingComponents:comp toDate:self options:0];
}

+(NSDate *)today{
    NSDate *date = [NSDate date];
    NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
    NSUInteger preservedComponents = (NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay);
    date = [calendar dateFromComponents:[calendar components:preservedComponents fromDate:date]];
    return date;
}

+ (NSDate *)todayByOffset:(NSInteger)offset
{
    NSDate *date = [NSDate date];
    NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
    NSUInteger preservedComponents = (NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay);
    NSDateComponents *componests = [calendar components:preservedComponents fromDate:date];
    componests.day += offset;
    date = [calendar dateFromComponents:componests];
    return date;
}

+ (NSDate *)todayByDate:(NSDate *)date
{
    if (date == nil) return [NSDate today];
    
    NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
    NSUInteger preservedComponents = (NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay);
    return [calendar dateFromComponents:[calendar components:preservedComponents fromDate:date]];
}

+ (NSDateComponents *)componetsWithTimeInterval:(NSTimeInterval)timeInterval
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    
    NSDate *date1 = [NSDate date];
    NSDate *date2 = [[NSDate alloc] initWithTimeInterval:timeInterval sinceDate:date1];
    
    unsigned int unitFlags =
    NSCalendarUnitSecond | NSCalendarUnitMinute | NSCalendarUnitHour |
    NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear;
    
    return [calendar components:unitFlags
                       fromDate:date1
                         toDate:date2
                        options:0];
}

+ (NSString *)timeDescriptionOfTimeInterval:(NSTimeInterval)timeInterval
{
    NSDateComponents *components = [self.class componetsWithTimeInterval:timeInterval];
    
    // if (components.hour > 0)
    {
        return [NSString stringWithFormat:@"%02d:%02d:%02d", (int)components.hour, (int)components.minute, (int)components.second];
    }
    
    //    else
    //    {
    //        return [NSString stringWithFormat:@"%02d:%02d", components.minute, components.second];
    //    }
}

//传入是相对当前时间的一个时间间隔  hasSecend 是否包含秒数
+ (NSString *)timeDescription1OfTimeInterval:(NSTimeInterval)timeInterval hasSecend:(BOOL)hasSecend
{
    NSMutableString *mStr = [NSMutableString string];
    if (hasSecend) {
        mStr = [[self timeDescription1OfTimeInterval:timeInterval] mutableCopy];
    }
    else
    {
        NSDateComponents *components = [self.class componetsWithTimeInterval:timeInterval];
        
        // BOOL hasPreComponents = NO;
        if(components.year>0)
        {
            [mStr appendFormat:NSLocalizedString(@"%ld年", nil),(long)components.year];
        }
        if(components.month>0)
        {
            [mStr appendFormat:NSLocalizedString(@"%ld月", nil),(long)components.month];
        }
        if(components.day>0)
        {
            [mStr appendFormat:NSLocalizedString(@"%ld天", nil),(long)components.day];
        }
        if(components.hour>0)
        {
            [mStr appendFormat:NSLocalizedString(@"%ld小时", nil),(long)components.hour];
        }
        if(components.minute>0)
        {
            [mStr appendFormat:NSLocalizedString(@"%ld分", nil),(long)components.minute];
        }
    }
    return mStr;
}

//传入是相对当前时间的一个时间间隔
+ (NSString *)timeDescription1OfTimeInterval:(NSTimeInterval)timeInterval
{
    NSDateComponents *components = [self.class componetsWithTimeInterval:timeInterval];
    NSMutableString *mStr = [NSMutableString string];
    
    // BOOL hasPreComponents = NO;
    if(components.year>0)
    {
        [mStr appendFormat:NSLocalizedString(@"%ld年", nil),(long)components.year];
    }
    if(components.month>0)
    {
        [mStr appendFormat:NSLocalizedString(@"%ld月", nil),(long)components.month];
    }
    if(components.day>0)
    {
        [mStr appendFormat:NSLocalizedString(@"%ld天", nil),(long)components.day];
    }
    if(components.hour>0)
    {
        [mStr appendFormat:NSLocalizedString(@"%ld小时", nil),(long)components.hour];
    }
    if(components.minute>0)
    {
        [mStr appendFormat:NSLocalizedString(@"%ld分", nil),(long)components.minute];
    }
    if(components.second>0)
    {
        [mStr appendFormat:NSLocalizedString(@"%ld秒", nil),(long)components.second];
    }
    
    return mStr;
}

-(NSInteger)unitIndexSinceDate:(NSDate *)refDate WithType:(time_unit_type)type
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    [calendar setMinimumDaysInFirstWeek:1];//设置每周至少要多少天
    NSInteger index = 0, index1 = 0;
    
    NSDate *d1 = [NSDate dateWithTimeInterval:calendar.timeZone.secondsFromGMT sinceDate:self];
    NSDate *d2 = [NSDate dateWithTimeInterval:calendar.timeZone.secondsFromGMT sinceDate:refDate];
    
    if (type == time_unit_year)
    {
        index = [calendar ordinalityOfUnit:NSCalendarUnitYear inUnit:NSCalendarUnitEra forDate:d1];
        index1 = [calendar ordinalityOfUnit:NSCalendarUnitYear inUnit:NSCalendarUnitEra forDate:d2];
    }
    else if (type == time_unit_month)
    {
        #warning 这个地方计算的结果有非预期的情况。例如：基于阳历NSCalendarIdentifierGregorian日历的情况下，2018-08-03 00:05:42 和 2018-08-03 00:05:43 计算出来的monthSince是不一样的
        index = [calendar ordinalityOfUnit:NSCalendarUnitMonth inUnit:NSCalendarUnitEra forDate:d1];
        index1 = [calendar ordinalityOfUnit:NSCalendarUnitMonth inUnit:NSCalendarUnitEra forDate:d2];
    }
    else if (type == time_unit_day)
    {
        index = [calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:d1];
        index1 = [calendar ordinalityOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitEra forDate:d2];
    }
    else if (type == time_unit_week)//NSCalendarUnitWeekday //NSCalendarUnitWeekOfYear
    {
        index = [calendar ordinalityOfUnit:NSCalendarUnitWeekOfYear inUnit:NSCalendarUnitEra forDate:d1];
        index1 = [calendar ordinalityOfUnit:NSCalendarUnitWeekOfYear inUnit:NSCalendarUnitEra forDate:d2];
    }
    
    return index - index1;

}

+(NSArray *)beginAndEndDateOfUnit:(NSInteger)unitAmount sinceDate:(NSDate *)refDate inUnit:(NSCalendarUnit)unit
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    [calendar setMinimumDaysInFirstWeek:1];//设置每周至少要多少天
    
    NSDate *dRef = [NSDate dateWithTimeInterval:calendar.timeZone.secondsFromGMT sinceDate:refDate];
    
    if([calendar respondsToSelector:@selector(dateByAddingUnit:value:toDate:options:)])
    {
        
        NSDate *d1 = [calendar dateByAddingUnit:unit value:unitAmount toDate:dRef options:NSCalendarMatchStrictly];
        NSDate *startDate;
        [calendar rangeOfUnit:unit startDate:&startDate interval:NULL forDate:d1];
        
        NSDate *d2 = [calendar dateByAddingUnit:unit value:unitAmount+1 toDate:dRef options:NSCalendarMatchStrictly];
        NSDate *nextStartDate;
        [calendar rangeOfUnit:unit startDate:&nextStartDate interval:NULL forDate:d2];
        NSDate *endDate = [nextStartDate dateByAddingTimeInterval:-0.001];
        
        return @[startDate,endDate];
    }
    else
    {
        NSDateComponents *components = [[NSDateComponents alloc] init];
        if (unit == NSCalendarUnitDay)
        {
            components.day = unitAmount;
        }
        else if (unit == NSCalendarUnitWeekOfYear)
        {
            components.weekOfYear = unitAmount;
        }
        else if (unit == NSCalendarUnitMonth)
        {
            components.month = unitAmount;
        }
        
        NSDate *d1 = [calendar dateByAddingComponents:components toDate:dRef options:NSCalendarMatchStrictly];
        NSDate *startDate;
        [calendar rangeOfUnit:unit startDate:&startDate interval:NULL forDate:d1];
        
        if (unit == NSCalendarUnitDay)
        {
            components.day += 1;
        }
        else if (unit == NSCalendarUnitWeekOfYear)
        {
            components.weekOfYear += 1;
        }
        else if (unit == NSCalendarUnitMonth)
        {
            components.month += 1;
        }
        
        NSDate *d2 = [calendar dateByAddingComponents:components toDate:dRef options:NSCalendarMatchStrictly];
        NSDate *nextStartDate;
        [calendar rangeOfUnit:unit startDate:&nextStartDate interval:NULL forDate:d2];
        NSDate *endDate = [nextStartDate dateByAddingTimeInterval:-0.001];
        
        return @[startDate, endDate];
    }
        return nil;
}

//自从2010年开始的时间

+(NSDate *)the2010Year
{
    static NSDate *the2010Year;
    if(!the2010Year)
        the2010Year = [NSDate dateFromFormatedString:@"2010-01-01 00:00:00" byFormat:@"yyyy-MM-dd HH:mm:ss"];
    return the2010Year;
}

-(NSInteger)unitIndexSince2010WithType:(time_unit_type)type
{
    return [self unitIndexSinceDate:[[self class] the2010Year] WithType:type];
}

+(NSArray *)beginAndEndDateOfUnitSince2010:(NSInteger)unitAmount inUnit:(NSCalendarUnit)unit
{
    return [self beginAndEndDateOfUnit:unitAmount sinceDate:[[self class] the2010Year] inUnit:unit];
}

-(NSInteger)countOfUnitSince1970ByUnitType:(time_unit_type)type
{
   // NSDate *refDate = [NSDate dateWithTimeIntervalSince1970:3600*24*30*5];
    NSDate *refDate = [NSDate dateWithTimeIntervalSince1970:0];
    NSCalendar *cal = [NSCalendar currentCalendar];
    
    NSDateComponents *componentsFrom;
    NSCalendarOptions opt = 0;
    
    if (type == time_unit_year)
    {
        componentsFrom = [cal components:NSCalendarUnitYear fromDate:refDate toDate:self options:opt];
        return componentsFrom.year;
    }
    else if (type == time_unit_month)
    {
        componentsFrom = [cal components:NSCalendarUnitMonth fromDate:refDate toDate:self options:opt];
        return componentsFrom.month;
    }
    else if (type == time_unit_day)
    {
        componentsFrom = [cal components:NSCalendarUnitDay fromDate:refDate toDate:self options:opt];
        return componentsFrom.day;
    }
    else if (type == time_unit_week)
    {
        componentsFrom = [cal components:NSCalendarUnitWeekOfYear fromDate:refDate toDate:self options:opt];
        return componentsFrom.weekOfYear;
    }
    
    return 0;

}

+ (NSInteger)correctWeekDayWith:(NSInteger)weekDay
{
    if (weekDay == 1) {
        return 7;
    }
    return weekDay - 1;
}




//传入 多少 秒，得到分钟，或小时单位的 NSString
+ (NSString*)getTimeStringWithTime:(NSInteger)time
{
    if (time < 3600)
    {
        if (time < 60) {
            return NSLocalizedString(@"少于1分钟", nil);
        } else {
            return [NSString stringWithFormat:NSLocalizedString(@"%ld分钟", nil),(long)time/60];
        }
    }
    else
    {
        if (time%3600/60 == 0) {
            return [NSString stringWithFormat:NSLocalizedString(@"%ld小时", nil),(long)(time/3600)];
        }
        return [NSString stringWithFormat:NSLocalizedString(@"%ld小时%ld分钟", nil),(long)(time/3600),(long)(time%3600/60)];
    }
}

//得到具体显示的时长
+ (NSString*)getTimeStringDetailWithTime:(NSInteger)time
{
    if (time < 3600) {
        float timeMin = time / 60;  //分
        float timeSec = time % 60;  //秒
        
        return [NSString stringWithFormat:@"%02.0f:%02.0f", timeMin, timeSec];
    }
    else {
        float timeHour = time / 3600;     //时
        float timeMin = time % 3600 / 60; //分
        float timeSec = time % 3600 % 60;  //秒
        
        return [NSString stringWithFormat:@"%02.0f:%02.0f:%02.0f", timeHour, timeMin, timeSec];
    }
}


+ (NSString *)getFormartTimeStringWith:(NSInteger)sec
{
    if (sec < 60) {
        return [NSString stringWithFormat:NSLocalizedString(@"%ld秒", nil),(long)sec];
    }
    //耗时
    int64_t time = sec;
    
    NSMutableString * timeString = [[NSMutableString alloc] initWithCapacity:20];
    
    int64_t daySecond = 86400;
    int64_t monthSecond = daySecond * 30;
    int64_t yearSecond = monthSecond * 12;
    
    int64_t year = time / yearSecond;
    time = (time % yearSecond);
    int64_t month = time / monthSecond;
    time = (time % monthSecond);
    int64_t day = time / daySecond;
    time = (time % daySecond);
    int64_t hours = time / 3600;
    time = (time % 3600);
    int64_t min = time/60;
    
    if (year > 0) {
        [timeString appendFormat:NSLocalizedString(@"%lld年", nil), year];
    }
    
    if (month > 0) {
        [timeString appendFormat:NSLocalizedString(@"%lld个月", nil), month];
        
        if (day == 0) {
            return timeString;
        }
    }
    
    
    if (day > 0) {
        [timeString appendFormat:NSLocalizedString(@"%lld天", nil), day];
        
        if (month > 0 || hours == 0) {
            return timeString;
        }
    }
    
    
    if (hours > 0) {
        [timeString appendFormat:NSLocalizedString(@"%lld小时", nil), hours];
        
        if (day > 0 || min == 0) {
            return timeString;
        }
        
    }
    
    //如果小时为0, 而且分也为0, 则返回"1分钟"
//    if (hours == 0 && min == 0 && sec >0) {
//        min = 1;
//    }

    
    if (min > 0) {
        [timeString appendFormat:NSLocalizedString(@"%lld分钟", nil), min];
    }
    else
    {
        [timeString appendString:NSLocalizedString(@"0分钟", nil)];
    }
    
    
    return timeString;
}

+ (NSDateComponents*)getDateComponentsWithDate:(NSDate*)date
{
    return [[NSCalendar currentCalendar] components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitWeekday fromDate:date];
}

- (NSString *)dailyString
{
    NSDateComponents *comp = [self datePart];
    return [NSString stringWithFormat:@"%ld-%ld-%ld",(long)comp.year,(long)comp.month,(long)comp.day];
}



+ (long long)currentTimeStamp
{
    NSString *timeStap = [NSString stringWithFormat:@"%ld000",(long)[[NSDate date]timeIntervalSince1970]];
    
    return [timeStap longLongValue];
}


+ (NSString*)identifierOfTimeStamp
{
    NSString *identifier = [NSString stringWithFormat:@"%ld",(long)[[NSDate date]timeIntervalSince1970]];
    
    return identifier;
}

+ (long long)iosTime:(long long)time
{
    long long iosTime = time;
    if ( time > 100000000000 ) {
        iosTime = time / 1000;
    }
    return iosTime;
}

+ (long long)serverTime:(long long)time
{
    long long serverTime = time*1000;
    
    return serverTime;
}


- (NSDate*)startTimeOfADay
{
    return [NSDate dateFromFormatedString:[NSString stringWithFormat:@"%ld-%ld-%ld 0:0:0",(long)self.year,(long)self.month,(long)self.day]];
}

- (NSDate*)endTimeOfADay
{
    return [NSDate dateFromFormatedString:[NSString stringWithFormat:@"%ld-%ld-%ld 23:59:59",(long)self.year,(long)self.month,(long)self.day]];
}

+ (NSString *)monthDescByMonth:(NSUInteger)index {
    
    NSArray *list = @[@"", @"一月", @"二月", @"三月", @"四月", @"五月", @"六月", @"七月", @"八月", @"九月", @"十月", @"十一月", @"十二月"];
    if (index < list.count) {
        return list[index];
    }
    return nil;
}


// Instantiate single date formatter
+ (NSDateFormatter *)internetDateTimeFormatter {
    @synchronized(self) {
        if (!_internetDateTimeFormatter) {
            NSLocale *en_US_POSIX = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
            _internetDateTimeFormatter = [[NSDateFormatter alloc] init];
            [_internetDateTimeFormatter setLocale:en_US_POSIX];
            [_internetDateTimeFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
        }
    }
    return _internetDateTimeFormatter;
}

// Get a date from a string - hint can be used to speed up
+ (NSDate *)dateFromInternetDateTimeString:(NSString *)dateString formatHint:(DateFormatHint)hint {
    // Keep dateString around a while (for thread-safety)
    NSDate *date = nil;
    if (dateString) {
        if (hint != DateFormatHintRFC3339) {
            // Try RFC822 first
            date = [NSDate dateFromRFC822String:dateString];
            if (!date) date = [NSDate dateFromRFC3339String:dateString];
        } else {
            // Try RFC3339 first
            date = [NSDate dateFromRFC3339String:dateString];
            if (!date) date = [NSDate dateFromRFC822String:dateString];
        }
    }
    // Finished with date string
    return date;
}

// See http://www.faqs.org/rfcs/rfc822.html
+ (NSDate *)dateFromRFC822String:(NSString *)dateString {
    // Keep dateString around a while (for thread-safety)
    NSDate *date = nil;
    if (dateString) {
        NSDateFormatter *dateFormatter = [NSDate internetDateTimeFormatter];
        @synchronized(dateFormatter) {
            
            // Process
            NSString *RFC822String = [[NSString stringWithString:dateString] uppercaseString];
            if ([RFC822String rangeOfString:@","].location != NSNotFound) {
                if (!date) { // Sun, 19 May 2002 15:21:36 GMT
                    [dateFormatter setDateFormat:@"EEE, d MMM yyyy HH:mm:ss zzz"];
                    date = [dateFormatter dateFromString:RFC822String];
                }
                if (!date) { // Sun, 19 May 2002 15:21 GMT
                    [dateFormatter setDateFormat:@"EEE, d MMM yyyy HH:mm zzz"];
                    date = [dateFormatter dateFromString:RFC822String];
                }
                if (!date) { // Sun, 19 May 2002 15:21:36
                    [dateFormatter setDateFormat:@"EEE, d MMM yyyy HH:mm:ss"];
                    date = [dateFormatter dateFromString:RFC822String];
                }
                if (!date) { // Sun, 19 May 2002 15:21
                    [dateFormatter setDateFormat:@"EEE, d MMM yyyy HH:mm"];
                    date = [dateFormatter dateFromString:RFC822String];
                }
            } else {
                if (!date) { // 19 May 2002 15:21:36 GMT
                    [dateFormatter setDateFormat:@"d MMM yyyy HH:mm:ss zzz"];
                    date = [dateFormatter dateFromString:RFC822String];
                }
                if (!date) { // 19 May 2002 15:21 GMT
                    [dateFormatter setDateFormat:@"d MMM yyyy HH:mm zzz"];
                    date = [dateFormatter dateFromString:RFC822String];
                }
                if (!date) { // 19 May 2002 15:21:36
                    [dateFormatter setDateFormat:@"d MMM yyyy HH:mm:ss"];
                    date = [dateFormatter dateFromString:RFC822String];
                }
                if (!date) { // 19 May 2002 15:21
                    [dateFormatter setDateFormat:@"d MMM yyyy HH:mm"];
                    date = [dateFormatter dateFromString:RFC822String];
                }
            }
            if (!date) NSLog(@"Could not parse RFC822 date: \"%@\" Possible invalid format.", dateString);
            
        }
    }
    // Finished with date string
    return date;
}

// See http://www.faqs.org/rfcs/rfc3339.html
+ (NSDate *)dateFromRFC3339String:(NSString *)dateString {
    // Keep dateString around a while (for thread-safety)
    NSDate *date = nil;
    if (dateString) {
        NSDateFormatter *dateFormatter = [NSDate internetDateTimeFormatter];
        @synchronized(dateFormatter) {
            
            // Process date
            NSString *RFC3339String = [[NSString stringWithString:dateString] uppercaseString];
            RFC3339String = [RFC3339String stringByReplacingOccurrencesOfString:@"Z" withString:@"-0000"];
            // Remove colon in timezone as it breaks NSDateFormatter in iOS 4+.
            // - see https://devforums.apple.com/thread/45837
            if (RFC3339String.length > 20) {
                RFC3339String = [RFC3339String stringByReplacingOccurrencesOfString:@":"
                                                                         withString:@""
                                                                            options:0
                                                                              range:NSMakeRange(20, RFC3339String.length-20)];
            }
            if (!date) { // 1996-12-19T16:39:57-0800
                [dateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ssZZZ"];
                date = [dateFormatter dateFromString:RFC3339String];
            }
            if (!date) { // 1937-01-01T12:00:27.87+0020
                [dateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSSZZZ"];
                date = [dateFormatter dateFromString:RFC3339String];
            }
            if (!date) { // 1937-01-01T12:00:27
                [dateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss"];
                date = [dateFormatter dateFromString:RFC3339String];
            }
            if (!date) NSLog(@"Could not parse RFC3339 date: \"%@\" Possible invalid format.", dateString);
            
        }
    }
    // Finished with date string
    return date;
}


@end
